#include "wl_mutex.h"

#include "wl_trace.h"

#include <errno.h>
#include <pthread.h>
#include <ak_thread.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

wl_int32 wl_mutex_create(const wl_char* name, OUT WL_MUTEX* mutex) {
    if (wl_null != mutex) {
        UNUSED(name);
        ak_mutexattr_t attr;
        if (ak_thread_mutexattr_init(&attr)) {
            WLLOGW("pthread_mutexattr_init fail");
            return -1;
        }
        ak_thread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
        if (-1 == ak_thread_mutex_init(mutex, &attr)) {
            WLLOGW("pthread_mutex_init fail");
            return -1;
        }

        return 0;
    }

    return -1;
}

wl_int32 wl_mutex_acquire(WL_MUTEX* mutex) {
    if (wl_null != mutex) {
        if (-1 == ak_thread_mutex_lock(mutex)) {
            WLLOGW("pthread_mutex_lock fail");
            return -1;
        }
        return 0;
    }
    return -1;
}

wl_int32 wl_mutex_try_acquire(WL_MUTEX* mutex, wl_uint32 timeout) {
    if (wl_null != mutex) {
        UNUSED(timeout);
        wl_int32 error = pthread_mutex_trylock(mutex);
        if (0 != error) {
            WLLOGW("pthread_mutex_trylock fail");
            if (EBUSY == error) {
                return 1;
            }
            return -1;
        }
        return 0;
    }
    return -1;
}

wl_int32 wl_mutex_release(WL_MUTEX* mutex) {
    if (wl_null != mutex) {
        if (-1 == ak_thread_mutex_unlock(mutex)) {
            WLLOGW("pthread_mutex_unlock fail");
            return -1;
        }
        return 0;
    }
    return -1;
}

wl_int32 wl_mutex_delete(WL_MUTEX* mutex) {
    if (wl_null != mutex) {
        if (-1 == ak_thread_mutex_destroy(mutex)) {
            WLLOGW("pthread_mutex_destroy fail");
            return -1;
        }
        return 0;
    }
    return -1;
}

#ifdef __cplusplus
}
#endif /* __cplusplus */
